package bs.aspect;

import java.lang.reflect.Method;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import bs.anno.Logger;
import bs.anno.RedisSupervisor;
import bs.entity.SysLog;
import bs.entity.User;
import bs.service.LogService;
import bs.util.Log;

/**
 * 
 * LoggerAdvice: 定义日志增强
 *
 * @author 姜治昊
 * @time 2017年11月3日 下午10:05:11
 */
@Aspect    
@Component 
public class LoggerAdvice {

	@Autowired
	private LogService logService;
	
	/**
	 * 用户动作
	 * execution(* bs.service.*.*(..))
	 */
	@Pointcut("@annotation(bs.anno.Logger)")
	public void logAdvice(){}
	
	/**
	 * 登录
	 */
	@Pointcut("@annotation(bs.anno.LoginLogger)")
	public void loginLogAdvice(){}
	
	/**
	 * 缓存
	 */
	@Pointcut("@annotation(bs.anno.RedisSupervisor)")
	public void redisCacheAdvice() {}
	
	/**
	 * 缓存异常日志
	 * @param joinPoint
	 * @param e
	 */
	@AfterThrowing(pointcut="redisCacheAdvice()", throwing="e")
	public void cacheAdvice(JoinPoint joinPoint,Throwable e) {
		String errorMsg = e.getMessage();
		String expName = e.getClass().getName();
		MethodSignature signatrue = (MethodSignature) joinPoint.getSignature();
		Method method = signatrue.getMethod();
		RedisSupervisor redisSupervisor = method.getAnnotation(RedisSupervisor.class);
		String description = redisSupervisor.description();
		if(!Log.isInint()) {
			Log.init();
		}
		Log.log("时间：" + (new Date()) + " Redis异常  " + expName + "  --  " + errorMsg, false);
		Log.log("           异常描述："+description, true);
	}
	
	/**
	 * 登录日志
	 */
	@After("loginLogAdvice()")
	public void loginAdvice(JoinPoint joinPoint) {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
		User user = (User) request.getSession().getAttribute("LOGIN_USER");
		SysLog sysLog = new SysLog(user, "用户登录", new Date());
		if(null == user || null == user.getUserId() || user.getUserId() <= 0) {
			sysLog.setLogResult("失败");
		} else {
			sysLog.setLogResult("成功");
		}
		logService.actionLog(sysLog);
	}
	
	/**
	 * 已经的登陆用户的动作日志
	 * @param joinPoint
	 */
	@Before("logAdvice()")
	public void requestAdvice(JoinPoint joinPoint) {
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
		User user = (User) request.getSession().getAttribute("LOGIN_USER");
		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
		Method method = signature.getMethod();
		Logger logger = method.getAnnotation(Logger.class);
		String description = logger.description();
		SysLog sysLog = new SysLog(user, description, new Date());
		logService.actionLog(sysLog);
	}

}
